/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package extension.game.zone;

import com.smartfoxserver.v2.api.CreateRoomSettings;
import com.smartfoxserver.v2.api.CreateRoomSettings.RoomExtensionSettings;
import com.smartfoxserver.v2.api.ISFSApi;
import com.smartfoxserver.v2.core.SFSEventType;
import com.smartfoxserver.v2.entities.Room;
import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.exceptions.SFSCreateRoomException;
import com.smartfoxserver.v2.extensions.SFSExtension;
import extension.game.database.Database;
import extension.game.room.Game;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import log.Debug;

/**
 *
 * @author daz
 */
public abstract class GameZoneExtension extends SFSExtension {

    public static String[] GROUP_LIST = {RoomGroup.LEVEL1, RoomGroup.LEVEL2,
        RoomGroup.LEVEL3,
        RoomGroup.LEVEL4, RoomGroup.LEVEL5, RoomGroup.LEVEL6,
        RoomGroup.LEVEL7, RoomGroup.LEVEL8, RoomGroup.LEVEL9,
        RoomGroup.LEVEL10};
    protected Response response;
    public static int numberTablePerRooms;
    public static int numberTable;
    public String zoneName;
    public String extensionClass;
    public String roomPrefix = "P";
    private Database database;

    @Override
    public abstract void init();

    public abstract void initResponse();

    private void loadConfig() {
        try {
            Properties prop = new Properties();
            //load a properties file from class path, inside static method
            prop.load(new FileInputStream("config.properties"));

            //get the property value and print it out
            numberTable = Integer.parseInt(prop.getProperty("number_tables"));
            numberTablePerRooms = Integer.parseInt(prop.getProperty("number_tables_per_level"));
            String isDebug = prop.getProperty("is_debug");
            String isShowLog = prop.getProperty("is_show_log");
            if ("true".equals(isDebug)) {
                Debug.isDebug = true;
            } else {
                Debug.isDebug = false;
            }
            if ("true".equals(isShowLog)) {
                Debug.isShowLog = true;
            } else {
                Debug.isShowLog = false;
            }
        } catch (IOException ex) {
            initConfig();
            loadConfig();
        }
    }

    private void initConfig() {
        Properties prop = new Properties();
        try {
            //set the properties value
            prop.setProperty("number_tables", "50");
            prop.setProperty("number_tables_per_level", "10");
            prop.setProperty("is_debug", "false");
            prop.setProperty("is_show_log", "false");
            //save properties to project root folder
            prop.store(new FileOutputStream("config.properties"), null);

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void startupExtension() {
        Debug.setExt(this);
        initResponse();
        loadConfig();
        Debug.i("init " + zoneName);
        database = new Database(getParentZone().getDBManager());
        createTable();
        addHandler();

    }

    public void addHandler() {
        addEventHandler(SFSEventType.USER_JOIN_ZONE, OnCountHandler.class);
        addEventHandler(SFSEventType.USER_DISCONNECT, OnCountHandler.class);
        addRequestHandler(Command.MONEY_JOIN, MoneyJoinHandler.class);
        addRequestHandler(Command.BET_MONEY_INFO, BetMoneyInfoHandler.class);
        addEventHandler(SFSEventType.USER_JOIN_ROOM, OnUserJoinRoom.class);
        addRequestHandler(Command.LIST_TABLE, ListTableInfoHandler.class);
        addRequestHandler(Command.TABLE_INFO, TableInfoHandler.class);
    }

    private void createTable() {
        Date date = new Date();
        Debug.d(zoneName);
        if (date.getMonth() >= 3) {
            return;
        }
        if (Debug.isDebug) {
            numberTable = 10;
            numberTablePerRooms = 5;
        }
        for (int i = 0; i < numberTable; i++) {
            makeTable(i + 1, GROUP_LIST[i / numberTablePerRooms]);
        }
    }

    private void makeTable(int tableName, String groupId) {
        CreateRoomSettings settings = new CreateRoomSettings();
        String roomName = roomPrefix + String.valueOf(tableName);
        settings.setName(roomName);
        settings.setGame(true);
        settings.setGroupId(groupId);
        RoomExtensionSettings extensionSetting =
                new CreateRoomSettings.RoomExtensionSettings(zoneName, extensionClass);
        settings.setExtension(extensionSetting);
        ISFSApi api = getApi();
        try {
            Room room = api.createRoom(getParentZone(), settings, null, false, null, false, true);
            room.setProperty("room_per_level", numberTablePerRooms);
            room.setProperty("number_tables", numberTable);
            int roomPerLevel = (Integer) room.getProperty("room_per_level");

        } catch (SFSCreateRoomException ex) {
        }
    }

    public Response getResponse() {
        return response;
    }

    public Database getDatabase() {
        return this.database;
    }

    public String getRoomPrefix() {
        return roomPrefix;
    }

    public void onJoinLobby(List<Room> listRooms, String groupName, User user) {
        List<String> listRoomNames = new LinkedList<String>();
        List<Long> listBets = new LinkedList<Long>();
        List<Integer> listNumberPlayer = new LinkedList<Integer>();
        for (Room r : listRooms) {
            listRoomNames.add("#" + r.getName());
            Integer numberPlayers = (Integer) r.getProperty(Flag.NUMBER_PLAYER);
            if (numberPlayers != null) {
                listNumberPlayer.add(numberPlayers);
            } else {
                listNumberPlayer.add(0);
            }
            Long betMoney = (Long) r.getProperty(Flag.BET_MONEY);
            if (betMoney != null) {
                listBets.add(betMoney);
            } else {
                listBets.add(0l);
            }
        }
        List<Integer> levelMoney = new LinkedList<Integer>();
        for (int i = 0, l = GameZoneExtension.numberTable / GameZoneExtension.numberTablePerRooms; i < l; i++) {
            levelMoney.add(Game.listRoomBet[i]);
        }
        int levelIndex = Integer.parseInt(groupName.substring(5)) - 1;
        response.sendListTable(levelMoney, levelIndex, listNumberPlayer, listRoomNames, listBets, groupName, user);
    }
}
